package MyFramePro.Service.Impl;

import MyFramePro.Domain.Entity.LoginUser;
import MyFramePro.Domain.Entity.Menu;
import MyFramePro.Domain.Entity.User;
import MyFramePro.Domain.ResponseResult;
import MyFramePro.Domain.Vo.BehindUserInfoVo;
import MyFramePro.Domain.Vo.MenuVo;
import MyFramePro.Domain.Vo.RouterVo;
import MyFramePro.Domain.Vo.UserInfoVo;
import MyFramePro.Mapper.BehindLoginMapper;
import MyFramePro.Mapper.UserMapper;
import MyFramePro.Service.BehindLoginService;
import MyFramePro.Utils.BeanCopyUtils;
import MyFramePro.Utils.JwtUtil;
import MyFramePro.Utils.RedisCache;
import MyFramePro.Utils.SecurityUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

@Service
public class BehindLoginServiceImpl extends ServiceImpl<BehindLoginMapper, User> implements BehindLoginService {

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private RedisCache redisCache;

    @Resource
    private MenuServiceImpl menuService;

    @Resource
    private RoleServiceImpl roleService;

    /**
     * 这里是后台管理登录功能
     */
    @Override
    public ResponseResult login(User user) {

        //1.进行认证的相关操作
        //1.1判断是否认证通过，不通过则给出提示信息
        UsernamePasswordAuthenticationToken authenticationToken
                = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("认证失败，当前用户不存在!");
        }

        //1.2认证通过，获取 userId，生成 token
        LoginUser loginUser =(LoginUser) authenticate.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String token = JwtUtil.createJWT(userId);


        //2.将用户信息放入 redis 中
        redisCache.setCacheObject("behind-login:" + userId,loginUser);

        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("token",token);
        return ResponseResult.okResult(hashMap);
    }

    /**
     * 这里是根据对应的权限与角色，显示对应的功能信息
     */
    @Override
    public ResponseResult<BehindUserInfoVo> getInfo() {

        //1.获取当前用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();

        //2.根据用户 ID 查询对应的权限信息
        List<String> parms=menuService.selectParmsByUserId(loginUser.getUser().getId());
        //2.1 根据用户 ID 查询对应角色信息
        List<String> roleKeyList=roleService.selectRoleKeyByUserId(loginUser.getUser().getId());

        //3.由于前端接收的字段，当前实体类不能够满足，所以这里使用 Vo 类型的对象
        User user = loginUser.getUser();
        UserInfoVo userInfoVo = BeanCopyUtils.myCopyBean(user, UserInfoVo.class);   //一转

        BehindUserInfoVo behindUserInfoVo = new BehindUserInfoVo(parms,roleKeyList,userInfoVo); //二转

        return ResponseResult.okResult(behindUserInfoVo);

    }


    /**
     * 这里是退出登录的功能
     */
    @Override
    public ResponseResult logout() {

        //1.获取当前认证用户的用户 ID
        Long userId = SecurityUtils.getUserId();

        //2.通过key，从 redis 中删除对应的用户信息
        redisCache.deleteObject("behind-login:"+userId);

        return ResponseResult.okResult();
    }


    /**
     *  Router 接口，查询 menus 中的信息为 tree 的形式
     */
//    @Override
//    public ResponseResult getRouters() {
//
//        //1.查询当前认证用户的 userId
//        Long userId = SecurityUtils.getUserId();
//
//        //2.查询 menus 的结果为 tree 形式
//        List<MenuVo> menuVos=menuService.selectRouterMenuTreeByUserId(userId);  //一转
//
////        List<MenuVo> menuVos = BeanCopyUtils.myCopyBeanList(menus, MenuVo.class);   //一转
//
//        RouterVo routerVo = new RouterVo(menuVos);  //二转
//
//        return ResponseResult.okResult(routerVo);
//    }


}
